package info.xmlprint.ui.referencesystem;

import info.xmlprint.core.referencesystem.PageMaster;
import info.xmlprint.core.referencesystem.PageMasterGroup;
import info.xmlprint.core.project.PrintProject;
import info.xmlprint.core.referencesystem.AbstractBaseGroup;
import info.xmlprint.core.referencesystem.AbstractBaseItem;
import info.xmlprint.ui.message.GuiMessages;
import info.xmlprint.ui.widgets.IObserverControl;
import info.xmlprint.ui.widgets.ISetupComposite;
import info.xmlprint.util.FileUtil;
import info.xmlprint.util.ResizeColumns;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;

public class PageMasterSetup extends Composite implements
		IObserverControl, ISetupComposite {

	private class LocalContentProvider implements ITreeContentProvider {

		@Override
		public void dispose() {
		}

		@Override
		public Object[] getChildren(Object parentElement) {
			return null;
		}

		@Override
		public Object[] getElements(Object list) {
			if (list instanceof PageMasterGroup) {
				return ((PageMasterGroup) list).getItems().toArray();
			}
			return null;
		}

		@Override
		public Object getParent(Object element) {
			return null;
		}

		@Override
		public boolean hasChildren(Object element) {
			return false;
		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}
	}

	private class LocalLabelProvider implements ITableLabelProvider {

		@Override
		public void addListener(ILabelProviderListener listener) {
		}

		@Override
		public void dispose() {
		}

		@Override
		public Image getColumnImage(Object element, int columnIndex) {
			return null;
		}

		@Override
		public String getColumnText(Object obj, int index) {
			if (obj instanceof PageMaster) {
				PageMaster pm = (PageMaster) obj;
				// col name
				if (index == 0) {
					return pm.getValueOf("name");
				} else {
					return "";
				}
			}
			return null;
		}

		@Override
		public boolean isLabelProperty(Object element, String property) {
			return false;
		}

		@Override
		public void removeListener(ILabelProviderListener listener) {
		}
	}
	
	private PageMasterComposite pmComposite;

	private AbstractBaseGroup pmGroup;

	private Shell pmShell;

	private TreeViewer treeViewer;

	private PrintProject printProject;

	public PageMasterSetup(Composite parent, int style) {
		super(parent, style);
		this.setLayout(new FillLayout());
		this.addDisposeListener(new DisposeListener() {
			@Override
			public void widgetDisposed(DisposeEvent e) {
				treeViewer.getControl().dispose();
				treeViewer = null;
				if (pmShell != null && !pmShell.isDisposed()) {
					pmShell.dispose();
				}
			}
		});

		initGui();
	}

	private void delItemAction(PageMaster pm) {
		AbstractBaseGroup group = pm.getGroup();
		group.remove(pm);
		updateControl();
	}

	public AbstractBaseGroup getPageMasterGroup() {
		return pmGroup;
	}

	private void initGui() {
		treeViewer = new TreeViewer(this, SWT.FULL_SELECTION | SWT.MULTI);
		final Tree tree = treeViewer.getTree();
		tree.setHeaderVisible(true);
		tree.setLinesVisible(true);
		TableLayout tableLayout = new TableLayout();
		tree.setLayout(tableLayout);

		TreeColumn nameCol = new TreeColumn(tree, SWT.NONE);
		nameCol.setText(GuiMessages.Fieldinformation_Name);

		TreeColumn contentCol = new TreeColumn(tree, SWT.NONE);
		contentCol.setText(GuiMessages.Fieldinformation_Content);

		treeViewer.setContentProvider(new LocalContentProvider() {
		});
		treeViewer.setLabelProvider(new LocalLabelProvider() {
		});

		tree.addListener(SWT.MouseDoubleClick, new Listener() {
			@Override
			public void handleEvent(Event e) {
				TreeItem treeItem = tree.getItem(new Point(e.x, e.y));
				if (treeItem != null) {
					PageMaster selectedPM = (PageMaster) treeItem
							.getData();
					openPMEditShell(selectedPM);
				} else
					openPMEditShell(null);
			}
		});

		tree.addListener(SWT.MenuDetect, new Listener() {
			@Override
			public void handleEvent(Event event) {
				final PageMaster selectedPM;

				if (tree.getSelection() == null || tree.getSelectionCount() < 1) {
					selectedPM = null;
				} else {
					TreeItem ti = tree.getSelection()[0];
					selectedPM = (PageMaster) ti.getData();
				}

				Menu menu = new Menu(tree.getShell(), SWT.POP_UP);

				MenuItem editItem = new MenuItem(menu, SWT.PUSH);
				editItem.setText(GuiMessages.General_Gui_Edit);
				editItem.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						openPMEditShell(selectedPM);
					}
				});
				if (selectedPM == null) {
					editItem.setEnabled(false);
				}

				MenuItem delItem = new MenuItem(menu, SWT.PUSH);
				delItem.setText(GuiMessages.General_Gui_Delete);
				delItem.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						for (AbstractBaseItem pm : pmGroup.getItems()) {
							if (pm.equals(selectedPM))
								continue;
						}

						if (MessageDialog.openConfirm(null, "",
								GuiMessages.Stileditor_Warning_AreYouSure)) {

							delItemAction(selectedPM);
						}
					}
				});
				if (selectedPM == null) {
					delItem.setEnabled(false);
				}

				new MenuItem(menu, SWT.SEPARATOR);

				MenuItem addItem = new MenuItem(menu, SWT.PUSH);
				addItem.setText(GuiMessages.General_Gui_Add);
				addItem.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						openPMEditShell(null);
					}
				});
				menu.setVisible(true);
			}
		});

		this.addControlListener(new ResizeColumns(this, tree));
	}

	/*
	 * Settings for selected paper format
	 */
	private void openPMEditShell(PageMaster pm) {
		if (pmShell == null) {
			pmShell = new Shell(this.getDisplay(), SWT.CLOSE | SWT.MIN
					| SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX);
			pmShell.setText(GuiMessages.Stileditor_PageLayout_Format);
			FileUtil.shellSetCenter(pmShell);
			pmShell.setLayout(new GridLayout());
			pmShell.addListener(SWT.Close, new Listener() {
				public void handleEvent(Event event) {
					pmShell.setVisible(false);
					event.doit = false;
				}
			});
			pmComposite = new PageMasterComposite(pmShell, SWT.NONE);
			pmComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
			pmComposite.registerObserver(this); 
			pmShell.pack();
		}
		pmShell.open();
		pmComposite.setPrintProject(printProject);
		pmComposite.setPageMasterGroup(pmGroup);
		
		pmComposite.setInput(pm);
	}

	@Override
	public void setPrintProject(PrintProject project) {
		printProject = project;
		pmGroup = printProject.getPageMasterGroup();
		treeViewer.setInput(pmGroup);
	}

	@Override
	public void updateControl() {
		treeViewer.refresh();
	}
}
